// Copyright (C) 2010, Scott W. Dunlop <swdunlop@gmail.com>
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//    * Redistributions of source code must retain the above copyright
//      notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//    * Neither the name of the <organization> nor the
//      names of its contributors may be used to endorse or promote products
//      derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
// ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#define NOSPEX_IMPL_SOURCE // Indicates that this is an implementation file.

#include "nospex.h"
#include "util.h"
#include "sdl.h"

#include <string.h>

void nx_handle_graph_event( 
    void* ctxt, nx_resource_p rsrc, int signal, double x, double y
){
    nx_graph_p graph = (nx_graph_p) ctxt;
    nx_link_p link;
    nx_node_p node;
    nx_info_p info;
    char* name;

    switch( signal ){
    case NX_GRAPH_CLICK_EVT:   // Called when the field is clicked by a pointer.
        FOREACH_LINK( graph, link ){
            nx_create_info( 
                (nx_element_p) nx_create_blip( link, NX_FROM_SRC, 1000 ),
                "blip!",
                5
            );
        };
        nx_request_graph_blips( graph );
        break;
    case NX_ELEMENT_CLICK_EVT:   // Called when a node is clicked by the pointer.
        nx_unlink_resource( rsrc );
        nx_request_graph_physics( graph );
        nx_request_graph_render( graph ); // Necessary if last one is unlinked.
        break;
    case NX_ELEMENT_ENTER_EVT:   // Called when a node is entered by the pointer.
        nx_create_info( (nx_element_p)rsrc, "Info.", 4 );
        nx_request_graph_render( graph ); 
        break;
    case NX_ELEMENT_LEAVE_EVT:   // Called when a node is left by the pointer.
        info = nx_element_info( (nx_element_p)rsrc );
        nx_unlink_info( info );
        nx_request_graph_render( graph ); 
        break;
    case NX_ELEMENT_UNLINK_EVT:  // Called when a node is unlinked.
        break;
    case NX_ELEMENT_DRAG_EVT:  // Called when a node is deleted.
        node = nx_to_node( rsrc );
        if( node != NULL ){
            nx_set_node_position( node, x, y );
            nx_request_graph_physics( graph );
            nx_request_graph_render( graph );
        };
        break;
    };
};

void make_star( nx_graph_p graph, int sides, int size ){
    int i, j; 
    nx_node_p prev,node,root = nx_create_node( graph );
    for( i = 0; i < sides; i ++ ){
        prev = root;
        for( j = 0; j < size; j ++ ){
            node = nx_create_node( graph );
            if( prev != NULL )nx_create_link( prev, node );
            prev = node;
        };
    }
};

int main( int argc, char* argv[] ){
    nx_graph_p     graph;
    nx_window_p    window;

    nx_node_p node, prev, root;
    int ct;
    
    nx_start_system_clock( );
    
    graph = nx_create_graph( 1000, 1000 );
    window = nx_create_window( graph );
    nx_set_graph_callback( graph, graph, nx_handle_graph_event );
    make_star( graph, 8, 4 );
    
    nx_request_graph_physics( graph );
    nx_window_loop( window );
    return 0;
}

